package com.ruoyi.web.controller.okr;

import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.enums.CountDataScope;
import com.ruoyi.system.enums.IntervalDataScope;
import com.ruoyi.system.enums.RemindType;
import com.ruoyi.system.enums.ScoreScope;
import com.ruoyi.system.service.IOkrCycleService;
import com.ruoyi.system.service.IOkrInfoService;
import com.ruoyi.system.service.IOkrInformService;
import io.lettuce.core.dynamic.annotation.Param;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by Bruce on 2021/8/12 9:48
 **/
@Controller
@RequestMapping("/dataKanban")
public class DataKanbanController extends BaseController {
    String prefix = "okr";

    @Autowired
    private IOkrCycleService okrCycleService;
    @Autowired
    private IOkrInfoService okrInfoService;
    @Autowired
    private IOkrInformService okrInformService;

    private Long cid;

    private List<KanbanData> list;

    private List<Long> alignedList;

    private String processInterval;

    private String okrCountInterval;

    private String scoreInterval;

    @RequiresPermissions("okr:info:view")
    @GetMapping()
    public String showDataKanban(Model model){
        List<OkrCycle> list = okrCycleService.selectOkrCycleList(new OkrCycle());
        model.addAttribute("cycleList", list);
        return prefix + "/dataKanban";
    }


    @PostMapping("/list")
    @ResponseBody
    public TableDataInfo showList(Long cycleId){
        startPage();
        cid = cycleId;
        SysUser user = ShiroUtils.getSysUser();
        //获取默认周期ID，就是第一个周期
        if (cycleId == null){
            List<OkrCycle> useCycleList = okrCycleService.selectOkrUseCycleList();
            cycleId = useCycleList.get(0).getId();
        }
        //把对齐量对应到每个部门员工
        KanbanBase base = new KanbanBase(user.getUserId(), user.getDeptId(), cycleId);
        list = okrInfoService.showKanban(base);
        List<KanbanData> listOfScore = okrInfoService.queryScoreCount(cycleId, user.getUserId(), user.getDeptId());
        for (KanbanData k1 : list){
            for (KanbanData k2 : listOfScore){
                if (k1.getUserId().equals(k2.getUserId())){
                    k1.setScoreCount(k2.getScoreCount());
                }
            }
        }
        return getDataTable(this.list);
    }

    /**
     * 数据看板的比例模块
     * @param kanbanData
     * @return
     */
    @RequestMapping("/rateOfData")
    @ResponseBody
    public KanbanData showRate(KanbanData kanbanData){
        if (cid == null){
            List<OkrCycle> useCycleList = okrCycleService.selectOkrUseCycleList();
            cid = useCycleList.get(0).getId();
        }
        SysUser user = ShiroUtils.getSysUser();
        alignedList = okrInfoService.sumOfAligned(cid, user.getUserId(), user.getDeptId());
        double notFill = okrInfoService.sumOfNotFill(cid, user.getUserId(), user.getDeptId());
        double sum = okrInfoService.sumOfSubordinates(cid, user.getUserId(), user.getDeptId());
        double sumOfAligned = alignedList.size();
        double sumOfScored = okrInfoService.sumOfScored(cid, user.getUserId(), user.getDeptId());
        double rateOfFill = (sum - notFill) / sum;
        double rateOfAligned = sumOfAligned / sum;
        double rateOfScored = sumOfScored / sum;
        kanbanData.setRateOfFill((rateOfFill * 100));
        kanbanData.setRateOfAlign(rateOfAligned * 100);
        kanbanData.setRateOfScore(rateOfScored * 100);
        return kanbanData;
    }

    @RequestMapping("/queryCycleId")
    @ResponseBody
    public void queryCycleId(Long cycleId){
        if (cycleId == null){
            List<OkrCycle> useCycleList = okrCycleService.selectOkrUseCycleList();
            cycleId = useCycleList.get(0).getId();
        }
        this.cid = cycleId;
    }

    @RequestMapping("/getCid")
    @ResponseBody
    public Long getCid(){
        return this.cid;
    }

    @RequestMapping("/showNoFillUsers")
    public String showNoFillUsers(){
        return prefix + "/remindFill";
    }

    @RequestMapping("/remindFillList")
    @ResponseBody
    public TableDataInfo queryRemindList(){
        startPage();
        for (KanbanData k : list){
            if (k.getFillCount() > 0){
                k.setFillStatus("已填写");
            }else{
                k.setFillStatus("未填写");
            }
        }
        return getDataTable(list);
    }

    @RequestMapping("/showNoAlignUsers")
    public String showNoAlignUsers(){
        return prefix + "/remindAlign";
    }

    @RequestMapping("/remindAlignList")
    @ResponseBody
    public TableDataInfo queryAlignList(){
        startPage();
        for (KanbanData k : list){
            if (alignedList.contains(k.getUserId())){
                k.setAlignStatus("已对齐");
            }else {
                k.setAlignStatus("存在未对齐");
            }
        }
        return getDataTable(list);
    }

    @RequestMapping("/queryNoScoreUsers")
    public String queryNoScoreUsers(){
        return prefix + "/remindScore";
    }

    @RequestMapping("/remindScoreList")
    @ResponseBody
    public TableDataInfo queryScoreList(){
        startPage();
        for (KanbanData k : list){
            if (k.getScoreCount() > 0){
                k.setScoreStatus("已打分");
            }else {
                k.setScoreStatus("未打分");
            }
        }
        return getDataTable(list);
    }

    /**
     * 根据不同类型的图表进行提醒
     * @param informData
     */
    @RequestMapping("/sendRemind")
    @ResponseBody
    public void sendRemind(@Param("inform") InformData informData){
        SysUser user = ShiroUtils.getSysUser();
        String cycleName = okrCycleService.selectOkrCycleById(cid).getCycleName();
        OkrInform okrInform = new OkrInform();
        String type = informData.getTypeId();
        if (type.equals(RemindType.FILL.toString())){
            okrInform.setContent("提醒您尽快在 [ " + cycleName + " ] 周期内填写OKR");
        }else if (type.equals(RemindType.ALIGN.toString())){
            okrInform.setContent("提醒您还没有在 [ " + cycleName + " ] 周期内对目标进行对齐");
        }else if (type.equals(RemindType.SCORE.toString())){
            okrInform.setContent("提醒您尽快在 [ " + cycleName + " ] 周期内对OKR进行打分");
        }
        okrInform.setUrl("okr/info");
        okrInform.setParentId(user.getUserId());
        okrInform.setUserId(informData.getUserId());
        okrInform.setCycleId(cid);
        okrInform.setParentName(user.getUserName());
        okrInform.setInformTime(DateUtils.getNowDate());
        okrInform.setAvatar(user.getAvatar());
        okrInform.setType("提醒");
        okrInformService.insertOkrInform(okrInform);
    }

    @RequestMapping("/queryOkrProcess")
    @ResponseBody
    public List<Integer> queryOkrProcess(){
        if (cid == null){
            List<OkrCycle> useCycleList = okrCycleService.selectOkrUseCycleList();
            cid = useCycleList.get(0).getId();
        }
        SysUser user = ShiroUtils.getSysUser();
        return okrInfoService.queryCountOfObjList(cid, user.getUserId(), user.getDeptId());
    }

    //硬编码，尝试用hashmap传到前端
    @RequestMapping("/queryOkrCount")
    @ResponseBody
    public List<OkrCount> queryOkrCount(){
        if (cid == null){
            List<OkrCycle> useCycleList = okrCycleService.selectOkrUseCycleList();
            cid = useCycleList.get(0).getId();
        }
        SysUser user = ShiroUtils.getSysUser();
        List<OkrCount> res = new ArrayList<>();
        res.add(new OkrCount(CountDataScope.ScopeOfA.toString(), 0));
        res.add(new OkrCount(CountDataScope.ScopeOfB.toString(), 0));
        res.add(new OkrCount(CountDataScope.ScopeOfC.toString(), 0));
        res.add(new OkrCount(CountDataScope.ScopeOfD.toString(), 0));
        List<KanbanData> list = okrInfoService.queryOkrCountResult(cid, user.getUserId(), user.getDeptId());
        for (KanbanData k : list){
            if (k.getFillCount() == 0){
                int value = res.get(0).getValue();
                res.get(0).setValue(++value);
            }else if (k.getFillCount() >= 1 && k.getFillCount() <= 2){
                int value = res.get(1).getValue();
                res.get(1).setValue(++value);
            }else if (k.getFillCount() >= 3 && k.getFillCount() <= 5){
                int value = res.get(2).getValue();
                res.get(2).setValue(++value);
            }else{
                int value = res.get(3).getValue();
                res.get(3).setValue(++value);
            }
        }
        return res;
    }


    @RequestMapping("/processInterval")
    @ResponseBody
    public void getProcessInterval(String name){
        this.processInterval = name;
    }

    @RequestMapping("/getOkrProcessList")
    public String getOkrProcessList(){
        return prefix + "/okrProcessList";
    }

    /**
     * OKR的进度分布图
     * @return
     */
    @RequestMapping("/queryOkrProcessList")
    @ResponseBody
    public TableDataInfo queryOkrProcessList(){
        startPage();
        SysUser user = ShiroUtils.getSysUser();
        List<KanbanData> list = new ArrayList<>();
        if (processInterval.equals(IntervalDataScope.ScopeOfB.toString())){
            list =  okrInfoService.queryOkrProcessList(cid, user.getUserId(), user.getDeptId(), 0, 30);
        }else if(processInterval.equals(IntervalDataScope.ScopeOfC.toString())){
            list =  okrInfoService.queryOkrProcessList(cid, user.getUserId(), user.getDeptId(), 30.1, 60);
        }else if (processInterval.equals(IntervalDataScope.ScopeOfD.toString())){
            list =  okrInfoService.queryOkrProcessList(cid, user.getUserId(), user.getDeptId(), 60.1, 90);
        }else {
            list =  okrInfoService.queryOkrProcessList(cid, user.getUserId(), user.getDeptId(), 90.1, 100);
        }
        return getDataTable(list);
    }

    @RequestMapping("/OkrCount")
    @ResponseBody
    public void getOkrCount(String name){
        this.okrCountInterval = name;
    }

    @RequestMapping("/getOkrCountList")
    public String getOkrCountList(){
        return prefix + "/okrCountList";
    }

    /**
     * OKR数量的员工分布表
     * @return
     */
    @RequestMapping("/queryOkrCountList")
    @ResponseBody
    public TableDataInfo queryOkrCountList(){
        SysUser user = ShiroUtils.getSysUser();
        List<KanbanData> list = okrInfoService.queryOkrCountList(cid, user.getUserId(), user.getDeptId());
        System.out.println(list);
        List<KanbanData> res = new ArrayList<>();
        if (okrCountInterval.equals(CountDataScope.ScopeOfA.toString())){
            for (KanbanData k : list){
                if (k.getFillCount() == 0){
                    res.add(k);
                }
            }
        }else if (okrCountInterval.equals(CountDataScope.ScopeOfB.toString())){
            for (KanbanData k : list){
                if (k.getFillCount() >= 1 && k.getFillCount() <= 2){
                    res.add(k);
                }
            }
        }else if (okrCountInterval.equals(CountDataScope.ScopeOfC.toString())){
            for (KanbanData k : list){
                if (k.getFillCount() >= 3 && k.getFillCount() <= 5){
                    res.add(k);
                }
            }
        }else {
            for (KanbanData k : list){
                if (k.getFillCount() > 5){
                    res.add(k);
                }
            }
        }
        System.out.println(res);
        return getDataTable(res);
    }

    @RequestMapping("/queryOkrScore")
    @ResponseBody
    public List<Integer> queryOkrScore(){
        if (cid == null){
            List<OkrCycle> useCycleList = okrCycleService.selectOkrUseCycleList();
            cid = useCycleList.get(0).getId();
        }
        SysUser user = ShiroUtils.getSysUser();
        return okrInfoService.queryOkrScoreBar(cid, user.getUserId(), user.getDeptId());
    }

    @RequestMapping("/scoreInterval")
    @ResponseBody
    public void getScoreInterval(String name){
        this.scoreInterval = name;
    }

    @RequestMapping("/getOkrScoreList")
    public String getOkrScoreList(){
        return prefix + "/okrScoreList";
    }

    @RequestMapping("/queryOkrScoreList")
    @ResponseBody
    public TableDataInfo queryOkrScoreList(){
        SysUser user = ShiroUtils.getSysUser();
        List<KanbanData> list = new ArrayList<>();
        if (scoreInterval.equals(ScoreScope.SCOPE_A.toString())){
            list = okrInfoService.queryOkrScoreList(cid, user.getUserId(), user.getDeptId(), 0, 0);
        }else if (scoreInterval.equals(ScoreScope.SCOPE_B.toString())){
            list = okrInfoService.queryOkrScoreList(cid, user.getUserId(), user.getDeptId(), 0.1, 0.3);
        }else if (scoreInterval.equals(ScoreScope.SCOPE_C.toString())){
            list = okrInfoService.queryOkrScoreList(cid, user.getUserId(), user.getDeptId(), 0.4, 0.6);
        }else if (scoreInterval.equals(ScoreScope.SCOPE_D.toString())){
            list = okrInfoService.queryOkrScoreList(cid, user.getUserId(), user.getDeptId(), 0.7, 0.9);
        }else {
            list = okrInfoService.queryOkrScoreList(cid, user.getUserId(), user.getDeptId(), 0.9, 1);
        }
        return getDataTable(list);
    }

}
